function varargout = slider_gui(varargin)
% SLIDER_GUI M-file for slider_gui.fig
%      SLIDER_GUI, by itself, creates a new SLIDER_GUI or raises the existing
%      singleton*.
%
%      H = SLIDER_GUI returns the handle to a new SLIDER_GUI or the handle to
%      the existing singleton*.
%
%      SLIDER_GUI('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in SLIDER_GUI.M with the given input arguments.
%
%      SLIDER_GUI('Property','Value',...) creates a new SLIDER_GUI or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before slider_gui_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to slider_gui_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help slider_gui

% Last Modified by GUIDE v2.5 16-Jul-2011 13:25:43

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @slider_gui_OpeningFcn, ...
                   'gui_OutputFcn',  @slider_gui_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before slider_gui is made visible.
function slider_gui_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to slider_gui (see VARARGIN)

% Choose default command line output for slider_gui
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes slider_gui wait for user response (see UIRESUME)
% uiwait(handles.figure1);


% --- Outputs from this function are returned to the command line.
function varargout = slider_gui_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;



function slider_editText_Callback(hObject, eventdata, handles)
% hObject    handle to slider_editText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of slider_editText as text
%        str2double(get(hObject,'String')) returns contents of slider_editText as a double


% --- Executes during object creation, after setting all properties.
function slider_editText_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider_editText (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)
%obtains the slider value from the slider component
sliderValue = get(handles.slider1,'Value');
 
%puts the slider value into the edit text component
set(handles.slider_editText,'String', num2str(sliderValue));

% Update handles structure
guidata(hObject, handles);

% --- Executes during object creation, after setting all properties.
function slider1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to slider1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
pageSize = 4096;    %size of each page processed
pageBufCount = 5;   %number of pages of buffering

runMaxSpeed = false; %When true, the processor is used much more heavily 
                     %(ie always at maximum), but the chance of skipping is 
                     %reduced
fileName = 'E:\FER\DIPLOMSKI\synth\synth\audio_samples\test2.wav';
playDeviceID = 4;
chanList = [1,2];
[fileSize Fs] = wavread(fileName, 'size');
%Fs = 44100;
fileLength = fileSize(1);
fileChanCount = fileSize(2);

if((fileChanCount < 1) || (fileChanCount > 2))
    error ('File must contain either 1 or 2 channels');
end

if(nargin<4)
    startPoint = 1;
else
    startPoint = max(1, startPoint);
end

if(nargin<5)
    endPoint = fileLength;
else
    endPoint = min(endPoint, fileLength);
end

if(startPoint > endPoint)
    fprintf('(startPoint > endPoint) so no samples to play\n');
    return
end

if ~isreal(chanList) || length(chanList) < 1 || length(chanList) > 2 ...
    || ndims(chanList)~=2 || size(chanList, 1)~=1

    error ('chanList must be a real row vector with 1 or 2 elements');
end

%Test if current initialisation is ok
if(playrec('isInitialised'))
    if(playrec('getSampleRate')~=Fs)
        fprintf('Changing playrec sample rate from %d to %d\n', playrec('getSampleRate'), Fs);
        playrec('reset');
    elseif(playrec('getPlayDevice')~=playDeviceID)
        fprintf('Changing playrec play device from %d to %d\n', playrec('getPlayDevice'), playDeviceID);
        playrec('reset');
    elseif(playrec('getPlayMaxChannel')<max(chanList))
        fprintf('Resetting playrec to configure device to use more output channels\n');
        playrec('reset');
    end
end

%Initialise if not initialised
if(~playrec('isInitialised'))
    fprintf('Initialising playrec to use sample rate: %d, playDeviceID: %d and no record device\n', Fs, playDeviceID);
    playrec('init', Fs, playDeviceID, -1);
    
    % This slight delay is included because if a dialog box pops up during
    % initialisation (eg MOTU telling you there are no MOTU devices
    % attached) then without the delay Ctrl+C to stop playback sometimes
    % doesn't work.
    pause(0.1);
end
    
if(~playrec('isInitialised'))
    error ('Unable to initialise playrec correctly');
elseif(playrec('getPlayMaxChannel')<max(chanList))
    error ('Selected device does not support %d output channels\n', max(chanList));
end

if(playrec('pause'))
    fprintf('Playrec was paused - clearing all previous pages and unpausing.\n');
    playrec('delPage');
    playrec('pause', 0);
end

pageNumList = [];

fprintf('Playing from sample %d to sample %d with a sample rate of %d samples/sec\n', startPoint, endPoint, Fs);
phase = 0;
for startSample = startPoint:pageSize:5e4
    endSample = min(startSample + pageSize - 1, endPoint);
    
    %y = wavread(fileName, [startSample endSample]);
    %y = wavread('sine.wav');
    f = get (handles.slider1, 'Value');
    [y,phase] = generate_sin_wave(f, Fs, pageSize, phase);
    y = y';
    y = [y,y];
    
    %if length(chanList) == 1 && fileChanCount == 2
    %    y = (y(:, 1) + y(:, 2)) / 2;
    %end

    %if length(chanList) == 2 && fileChanCount == 1
    %    y = [y, y];
    %end
    
    pageNumList = [pageNumList playrec('play', y, chanList)];

    if(startSample==startPoint)
        %This is the first time through so reset the skipped sample count
        playrec('resetSkippedSampleCount');
    end
    
    % runMaxSpeed==true means a very tight while loop is entered until the
    % page has completed whereas when runMaxSpeed==false the 'block'
    % command in playrec is used.  This repeatedly suspends the thread
    % until the page has completed, meaning the time between page
    % completing and the 'block' command returning can be much longer than
    % that with the tight while loop
    if(length(pageNumList) > pageBufCount)
        if(runMaxSpeed)
            while(playrec('isFinished', pageNumList(1)) == 0)
            end
        else        
            playrec('block', pageNumList(1));
        end

        pageNumList = pageNumList(2:end);
    end
end

fprintf('Playback complete with %d samples worth of glitches\n', playrec('getSkippedSampleCount'));
guidata(hObject, handles);
    
